package net.dotool;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;

/**
 * @author 李岩飞
 * @email eliyanfei@126.com 2018年1月15日 上午10:25:54
 * 
 */
public class CollectionTools {
	/**
	 * 判断数组是否为空
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isEmpty(Collection<? extends Object> obj) {
		return obj == null || obj.size() == 0;
	}

	public static boolean isEmpty(Map<? extends Object, ? extends Object> obj) {
		return obj == null || obj.size() == 0;
	}

	/**
	 * 判断数组是否为空
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isEmpty(Object[] obj) {
		return obj == null || obj.length == 0;
	}

	/**
	 * 创建新的集合
	 * 
	 * @param cla
	 * @param datas
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T, M> T newCollection(Class<T> cla, M... datas) {
		T t = null;
		try {
			t = cla.newInstance();
			if (datas != null) {
				Collection<M> col = (Collection<M>) t;
				for (int i = 0; i < datas.length; i++) {
					col.add(datas[i]);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return t;
	}

	/**
	 * 是否有空值
	 * 
	 * @param array
	 * @return
	 */
	public static boolean hasNull(Object[] array) {
		if (array == null)
			return true;
		for (Object obj : array) {
			if (obj == null)
				return true;
		}
		return false;
	}

	/**
	 * 新建一个HashSet
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param ts
	 *            元素数组
	 * @return HashSet对象
	 */
	@SafeVarargs
	public static <T> HashSet<T> newHashSet(T... ts) {
		return newHashSet(false, ts);
	}

	/**
	 * 新建一个HashSet
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param isSorted
	 *            是否有序，有序返回 {@link LinkedHashSet}，否则返回 {@link HashSet}
	 * @param ts
	 *            元素数组
	 * @return HashSet对象
	 */
	@SafeVarargs
	public static <T> HashSet<T> newHashSet(boolean isSorted, T... ts) {
		if (null == ts) {
			return isSorted ? new LinkedHashSet<T>() : new HashSet<T>();
		}
		int initialCapacity = Math.max((int) (ts.length / .75f) + 1, 16);
		HashSet<T> set = isSorted ? new LinkedHashSet<T>(initialCapacity) : new HashSet<T>(initialCapacity);
		for (T t : ts) {
			set.add(t);
		}
		return set;
	}

	/**
	 * 新建一个HashSet
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param collection
	 *            集合
	 * @return HashSet对象
	 */
	public static <T> HashSet<T> newHashSet(Collection<T> collection) {
		return newHashSet(false, collection);
	}

	/**
	 * 新建一个HashSet
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param isSorted
	 *            是否有序，有序返回 {@link LinkedHashSet}，否则返回{@link HashSet}
	 * @param collection
	 *            集合，用于初始化Set
	 * @return HashSet对象
	 */
	public static <T> HashSet<T> newHashSet(boolean isSorted, Collection<T> collection) {
		return isSorted ? new LinkedHashSet<T>(collection) : new HashSet<T>(collection);
	}

	/**
	 * 新建一个HashSet
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param isSorted
	 *            是否有序，有序返回 {@link LinkedHashSet}，否则返回{@link HashSet}
	 * @param iter
	 *            {@link Iterator}
	 * @return HashSet对象
	 * @since 3.0.8
	 */
	public static <T> HashSet<T> newHashSet(boolean isSorted, Iterator<T> iter) {
		if (null == iter) {
			return newHashSet(isSorted, (T[]) null);
		}
		final HashSet<T> set = isSorted ? new LinkedHashSet<T>() : new HashSet<T>();
		while (iter.hasNext()) {
			set.add(iter.next());
		}
		return set;
	}

	/**
	 * 新建一个HashSet
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param isSorted
	 *            是否有序，有序返回 {@link LinkedHashSet}，否则返回{@link HashSet}
	 * @param enumration
	 *            {@link Enumeration}
	 * @return HashSet对象
	 * @since 3.0.8
	 */
	public static <T> HashSet<T> newHashSet(boolean isSorted, Enumeration<T> enumration) {
		if (null == enumration) {
			return newHashSet(isSorted, (T[]) null);
		}
		final HashSet<T> set = isSorted ? new LinkedHashSet<T>() : new HashSet<T>();
		while (enumration.hasMoreElements()) {
			set.add(enumration.nextElement());
		}
		return set;
	}

	/**
	 * 新建一个ArrayList
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param values
	 *            数组
	 * @return ArrayList对象
	 */
	@SafeVarargs
	public static <T> ArrayList<T> newArrayList(T... values) {
		if (null == values) {
			return new ArrayList<>();
		}
		ArrayList<T> arrayList = new ArrayList<T>(values.length);
		for (T t : values) {
			arrayList.add(t);
		}
		return arrayList;
	}

	/**
	 * 新建一个ArrayList
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param collection
	 *            集合
	 * @return ArrayList对象
	 */
	public static <T> ArrayList<T> newArrayList(Collection<T> collection) {
		if (null == collection) {
			return new ArrayList<>();
		}
		return new ArrayList<T>(collection);
	}

	/**
	 * 新建一个ArrayList<br>
	 * 提供的参数为null时返回空{@link ArrayList}
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param iterable
	 *            {@link Iterable}
	 * @return ArrayList对象
	 * @since 3.1.0
	 */
	public static <T> ArrayList<T> newArrayList(Iterable<T> iterable) {
		return (null == iterable) ? new ArrayList<T>() : newArrayList(iterable.iterator());
	}

	/**
	 * 新建一个ArrayList<br>
	 * 提供的参数为null时返回空{@link ArrayList}
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param iter
	 *            {@link Iterator}
	 * @return ArrayList对象
	 * @since 3.0.8
	 */
	public static <T> ArrayList<T> newArrayList(Iterator<T> iter) {
		final ArrayList<T> list = new ArrayList<>();
		if (null == iter) {
			return list;
		}
		while (iter.hasNext()) {
			list.add(iter.next());
		}
		return list;
	}

	/**
	 * 新建一个ArrayList<br>
	 * 提供的参数为null时返回空{@link ArrayList}
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param enumration
	 *            {@link Enumeration}
	 * @return ArrayList对象
	 * @since 3.0.8
	 */
	public static <T> ArrayList<T> newArrayList(Enumeration<T> enumration) {
		final ArrayList<T> list = new ArrayList<>();
		if (null == enumration) {
			return list;
		}
		while (enumration.hasMoreElements()) {
			list.add(enumration.nextElement());
		}
		return list;
	}

	/**
	 * 以 conjunction 为分隔符将集合转换为字符串
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param iterable
	 *            {@link Iterable}
	 * @param conjunction
	 *            分隔符
	 * @return 连接后的字符串
	 */
	public static <T> String join(Iterable<T> iterable, CharSequence conjunction) {
		if (null == iterable) {
			return null;
		}
		return join(iterable.iterator(), conjunction);
	}

	/**
	 * 以 conjunction 为分隔符将集合转换为字符串
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param iterable
	 *            {@link Iterable}
	 * @param conjunction
	 *            分隔符
	 * @param prefix
	 *            每个元素添加的前缀，null表示不添加
	 * @param suffix
	 *            每个元素添加的后缀，null表示不添加
	 * @return 连接后的字符串
	 * @since 4.0.10
	 */
	public static <T> String join(Iterable<T> iterable, CharSequence conjunction, String prefix, String suffix) {
		if (null == iterable) {
			return null;
		}
		return join(iterable.iterator(), conjunction, prefix, suffix);
	}

	/**
	 * 以 conjunction 为分隔符将集合转换为字符串<br>
	 * 如果集合元素为数组、{@link Iterable}或{@link Iterator}，则递归组合其为字符串
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param iterator
	 *            集合
	 * @param conjunction
	 *            分隔符
	 * @return 连接后的字符串
	 */
	public static <T> String join(Iterator<T> iterator, CharSequence conjunction) {
		return join(iterator, conjunction, null, null);
	}

	/**
	 * 以 conjunction 为分隔符将集合转换为字符串<br>
	 * 如果集合元素为数组、{@link Iterable}或{@link Iterator}，则递归组合其为字符串
	 * 
	 * @param <T>
	 *            集合元素类型
	 * @param iterator
	 *            集合
	 * @param conjunction
	 *            分隔符
	 * @param prefix
	 *            每个元素添加的前缀，null表示不添加
	 * @param suffix
	 *            每个元素添加的后缀，null表示不添加
	 * @return 连接后的字符串
	 * @since 4.0.10
	 */
	public static <T> String join(Iterator<T> iterator, CharSequence conjunction, String prefix, String suffix) {
		if (null == iterator) {
			return null;
		}

		final StringBuilder sb = new StringBuilder();
		boolean isFirst = true;
		T item;
		while (iterator.hasNext()) {
			if (isFirst) {
				isFirst = false;
			} else {
				sb.append(conjunction);
			}

			item = iterator.next();
			if (ArrayTools.isArray(item)) {
				sb.append(ArrayTools.join(ArrayTools.wrap(item), conjunction, prefix, suffix));
			} else if (item instanceof Iterable<?>) {
				sb.append(join((Iterable<?>) item, conjunction, prefix, suffix));
			} else if (item instanceof Iterator<?>) {
				sb.append(join((Iterator<?>) item, conjunction, prefix, suffix));
			} else {
				sb.append(StringTools.wrap(String.valueOf(item), prefix, suffix));
			}
		}
		return sb.toString();
	}
}
